﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Platform.ObjectModel;
using Platform.Storage.Entity;
using Platform.Storage.Impl;

namespace Platform.Linq
{

	/// <summary>
	/// Realiza a pesquisa de documentos no banco de dados
	/// </summary>
	internal sealed class DynamicQueryProvider : IQueryProvider
	{

		/// <summary>
		/// 
		/// </summary>
		/// <param name="translator"></param>
		/// <param name="materializer"></param>
		internal DynamicQueryProvider( DataObjectContext dbContext, Library library )
		{
			Debug.Assert( dbContext != null );
			Debug.Assert( library != null );

			this.DbContext = dbContext;
			this.Library = library;
			//this.Materializer = materializer;
		}

		/// <summary>
		/// Obtém ou define a biblioteca de documentos que está utilizando esse provider
		/// </summary>
		public Library Library
		{ get; private set; }

		/// <summary>
		/// Obtém ou define a conexão com o banco de dados
		/// </summary>
		public DataObjectContext DbContext
		{ get; private set; }

		/// <summary>
		/// Obtém o objeto que realiza o mapeamento entre a expressão da query para a expressão
		/// que é executada no repositório
		/// </summary>
		//public EntityQueryTranslator Translator
		//{ get; private set; }

		/// <summary>
		/// Obtém ou define o objeto utilizado para materializar as novas instâncias
		/// </summary>
		//public EntityDataObjectMaterializer Materializer
		//{ get; private set; }
		//public DataObjectMaterializer Materializer
		//{ get; private set; }

		#region IQueryProvider Members

		public IQueryable<TElement> CreateQuery<TElement>( Expression expression )
		{
			return new EntityDynamicQuery<TElement>( this.DbContext.Fields, this.DbContext.Relationships, this, this.Library ) { Expression = expression };
		}

		public IQueryable CreateQuery( Expression expression )
		{
			throw new NotSupportedException();
		}

		public TResult Execute<TResult>( Expression expression )
		{
			var executor = new DynamicQueryExecutor( this.Library );

			var values = executor.Execute<TResult>( expression );
			return values;
		}

		public object Execute( Expression expression )
		{
			throw new NotImplementedException();
		}

		#endregion
	}
}
